<!--
 * @Description: 
 * @Version: 0.1
 * @Autor: Civet
 * @Date: 2019-08-02 16:04:58
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2019-09-28 17:55:57
 -->
<template>
  <div class="my-tabs"
       ref="myTabs">
    <div class="iconfont icon-jiantouleft-copy prev"
         @click="prev"
         v-show="getIsOverFlowTabs"></div>
    <div class="out-my-tabs"
         ref="outMyTabs">
      <div ref="scrollTabs"
           class="tab-box">
        <ul class="tabs">
          <li v-for="(item,index) in tabs"
              :key="index"
              :class="item.path === curPath?'active':''"
              @click.stop="tabClick(item,index)"
              @contextmenu="contextmenu($event,item,index)">
            {{item.title}}
            <i class="del iconfont icon-shanchu"
               @click.stop="delClick(item,index)"></i>
          </li>
        </ul>
      </div>
    </div>
    <div class="iconfont icon-jiantouright-copy next"
         @click="next"
         v-show="getIsOverFlowTabs"></div>
    <div v-if="isShowPromptBox"
         class="prompt-box">
      <div class="mask"
           @click="isShowPromptBox = false;"
           @contextmenu="contextmenuClose"></div>
      <ul class="prompt"
          :style="promptStyle"
          @contextmenu="contextmenuClose">
        <li v-for="(item,index) in promptData"
            :key="item.id"
            @click="promptClick(index,item)">{{item.title}}</li>
      </ul>
    </div>
  </div>
</template>
<script type="text/ecmascript-6">
import { mapActions, mapGetters } from 'Vuex';
export default {
  name: 'MyTabs',
  components: {},
  props: {},
  data () {
    return {
      isShowPromptBox: false, // 是否显示右键弹窗
      promptStyle: {// 右键弹窗的样式--位置
        left: 0,
        top: 0
      },
      promptData: [
        { title: '关闭当前', id: 0 },
        { title: '关闭其他', id: 1 },
        { title: '关闭全部', id: 2 }
      ],
      curPath: '', // 当前路径
      configMap: {}, // 侧边栏的映射表
      tabs: [
        // {
        //   title: '欢迎页面',
        //   path: '/frame/HelloWorld'
        // }
      ], // tab栏目的菜单
      fristPath: '/frame',
      prevIndex: 0,
    };
  },
  methods: {
    ...mapActions(['addAddkeepLiveInclude', 'delAddkeepLiveInclude', 'resetAddKeepLiveInclude', 'setOverFlowTabs']),
    /**
     * tab项的点击事件
     * @param {Object} item
     * @param {Number} index
     */
    tabClick (item, index) {
      this.curPath = item.path;
      this.$router.push({ path: this.curPath });
    },
    /**
     * tab项的点击删除按钮事件
     * @param {Object} item
     * @param {Number} index
     */
    delClick (item, index) {
      // 清除tab
      this.tabs.splice(index, 1);

      this.makeMove();

      // 清除缓存
      this.delAddkeepLiveInclude(index);
      let tabs = this.tabs;
      let len = tabs.length;
      // 如果删除的项是选中的，那么默认调转到最后一项
      if (item.path === this.curPath) {
        let path = '';
        if (len === 0) {
          this.curPath = '';
          path = this.fristPath;
        } else {
          path = tabs[len - 1].path;
          this.curPath = path;
        }
        this.$router.push({ path });
      }
    },
    /**
     * 根据path查看tabs是否存在
     * @param {String} path 路径
     * @returns {*} 配置项  如果为null代表没有该配置项
     */
    hasTbasByPath (path) {
      let tabs = this.tabs;
      let curTab = null;
      for (let index = 0, len = tabs.length; index < len; index++) {
        if (tabs[index].path === path) {
          curTab = tabs[index];
          curTab.index = index;
        }
      }
      return curTab;
    },
    /**
     * 根据路径获得对应的配置项
     * @param {Object} data 路径
     */
    setConfigMap (data) {
      for (let item of data) {
        let lists = item.lists;
        let isLeaf = lists ? lists.length === 0 : true;
        if (isLeaf) {
          this.configMap[item.path] = item;
        } else {
          this.setConfigMap(item.lists);
        }
      }
    },
    /**
     * 设置tabs栏目的添加或者跳转
     * @param {Object} route 当前的路由地址
     */
    setTabs (route) {
      console.log('route', route)
      let path = route.path;
      console.log('path', path)
      // 路径至匹配前三
      let pathArr = path.split("/");
      pathArr.length = 3;
      path = pathArr.join("/");

      let curConfig = this.hasTbasByPath(path);
      console.log('curConfig', curConfig)

      if (curConfig) {
        this.curPath = curConfig.path;
      } else {
        this.curPath = path;
        curConfig = this.configMap[path];

        if (!curConfig) {
          curConfig = {
            'title': '404页面',
            'path': path
          };
        }
        this.tabs.push(curConfig);
        this.addAddkeepLiveInclude(route.name);

        this.$nextTick(() => {
          let outW = this.$refs.outMyTabs.offsetWidth;
          let scrollW = this.$refs.scrollTabs.offsetWidth;
          let fool = Math.floor(scrollW / outW);

          if (fool > this.prevIndex) {
            this.$refs.scrollTabs.style.left = -fool * outW + "px";
            this.prevIndex = fool;
          }

          if (this.$refs.scrollTabs.offsetWidth >= this.$refs.outMyTabs.offsetWidth) {
            this.setOverFlowTabs(true);
          } else {
            this.setOverFlowTabs(false);
          }
        })
      }
    },
    /**
     *  弹窗上面的选项按钮点击后触发
     * @param {Number} index 点击了第几个
     * @param {Object} item 点击了这个项的信息
     */
    promptClick (index, item) {
      this.isShowPromptBox = false;
      switch (item.id) {
        case 0:// 关闭当前
          this.delClick(this.curElItem, this.curElIndex);
          break;
        case 1:// 关闭其他
          this.tabs = this.tabs.splice(this.curElIndex, 1);
          this.resetAddKeepLiveInclude(this.keepLiveInclude.splice(this.curElIndex, 1));
          this.curPath = this.curElItem.path;
          this.makeMove();
          break;
        case 2:// 关闭全部
          this.tabs = [];
          this.resetAddKeepLiveInclude([]);
          this.$router.push({ path: this.fristPath });
          if (this.curElItem.path === this.fristPath) {
            this.setTabs(this.$route);
          }
          this.makeMove();
          break;
      }
    },
    /**
     * 拦截右键，并关闭菜单
     * @param {Object} event event
     */
    contextmenuClose (event) {
      // 鼠标右键拦截
      event.preventDefault ? event.preventDefault() : (event.returnValue = false);
      this.isShowPromptBox = false;
    },
    /**
     * 拦截右键，并弹出菜单
     * @param {Object} event event
     * @param {Object} item item项的数据
     * @param {Number} index 索引
     */
    contextmenu (event, item, index) {
      this.curElItem = item;
      this.curElIndex = index;
      let outW = this.$refs.outMyTabs.offsetWidth;
      // 鼠标右键拦截
      event.preventDefault ? event.preventDefault() : (event.returnValue = false);
      console.log('右键', item, index);
      this.isShowPromptBox = true;
      this.promptStyle.left = (event.layerX - this.prevIndex * outW) + 'px';
      this.promptStyle.top = event.layerY + 'px';
    },
    prev () {
      let outW = this.$refs.outMyTabs.offsetWidth; // 300 不变的
      this.prevIndex -= 1;
      if (this.prevIndex <= 0) {
        this.prevIndex = 0;
      }
      this.$refs.scrollTabs.style.left = -this.prevIndex * outW + "px";
    },
    next () {
      let outW = this.$refs.outMyTabs.offsetWidth; // 300 不变的
      let scrollW = this.$refs.scrollTabs.offsetWidth; // 增加就越长
      let fool = Math.floor(scrollW / outW);
      this.prevIndex += 1;
      if (this.prevIndex >= fool) {
        this.prevIndex = fool;
      }
      this.$refs.scrollTabs.style.left = -this.prevIndex * outW + "px";
    },
    makeMove () {
      this.$nextTick(() => {
        let outW = this.$refs.outMyTabs.offsetWidth;
        let scrollW = this.$refs.scrollTabs.offsetWidth;
        let fool = Math.floor(scrollW / outW);

        if (fool < this.prevIndex) {
          this.$refs.scrollTabs.style.left = -fool * outW + "px";
          this.prevIndex = fool;
        }

        if (scrollW >= outW) {
          this.setOverFlowTabs(true);
        } else {
          this.setOverFlowTabs(false);
        }
      })
    }
  },
  computed: {
    ...mapGetters(['keepLiveInclude', 'getIsOverFlowTabs', 'getTabs'])
  },
  watch: {
    $route (newV) {
      this.setTabs(newV);
    },
    getTabs (newV) {
      this.setConfigMap(newV);
      this.setTabs(this.$route);
    }
  },
  mounted () {

  },
  destroyed () {
  }
};
</script>
<style scoped lang="less">
.hide {
  width: 0.2rem;
  height: 0.4rem;
  line-height: 0.4rem;
  text-align: center;
  z-index: 10;
  background-color: #fff;
  cursor: pointer;
  box-sizing: border-box;
  color: #909399;
  font-size: 0.16rem;
  box-shadow: 1px 1px 5px #303133;
}

.my-tabs {
  position: relative;

  .out-my-tabs {
    height: 0.5rem;
    width: 100%;
    /*flex: 1;*/
    overflow: hidden;
    position: relative;
    animation: myfirst;

    .tab-box {
      position: absolute;
      left: 0;
      top: 0;
      height: 0.5rem;
      transition: left 1s;
      -moz-transition: left 1s; /* Firefox 4 */
      -webkit-transition: left 1s; /* Safari and Chrome */
      -o-transition: left 1s; /* Opera */
      white-space: nowrap;
      display: inline-block;

      .tabs {
        height: 0.5rem;
        display: flex;
        /*display: -webkit-box;*/
        align-items: center;
        margin-block-start: 0;
        margin-block-end: 0;
        margin-inline-start: 0;
        margin-inline-end: 0;
        padding-inline-start: 0;
        box-sizing: border-box;
        border-bottom: 0.01rem solid #e6e6e6;

        > li {
          cursor: pointer;
          display: flex;
          align-items: center;
          margin: 0 0.05rem;
          padding: 0.05rem 0.08rem;
          border: 0.01rem solid #e6e6e6;
          font-size: 0.14rem;
          color: rgb(109, 114, 132);

          &.active {
            background-color: #66b1ff;
            border-color: #66b1ff;
            color: #fff;

            &::before {
              content: "";
              width: 0.08rem;
              height: 0.08rem;
              margin: 0 0.08rem 0 0;
              border-radius: 50%;
              background-color: #fff;
              display: inline-block;
            }

            i {
              color: #fff;
              opacity: 0.7;
            }
          }

          .del {
            margin-left: 0.1rem;
            font-size: 0.14rem;
            color: #2d3a4b;
            opacity: 0.5;

            &:hover {
              color: #a00;
            }
          }
        }
      }
    }
  }

  .prev:extend(.hide) {
    position: absolute;
    left: -5px;
    top: 0.05rem;
  }

  .next:extend(.hide) {
    position: absolute;
    right: -5px;
    top: 0.05rem;
  }

  .prompt-box {
    .mask {
      position: fixed;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
    }

    .prompt {
      z-index: 1000;
      position: absolute;
      left: 0;
      top: 0;
      padding: 0.1rem 0;
      max-width: 2rem;
      border: 1px solid #eeeeee;
      background-color: #fff;
      border-radius: 0.05rem;

      > li {
        padding: 0.05rem 0.2rem;

        &:hover {
          background-color: #2d3a4b;
          color: #fff;
          cursor: pointer;
        }
      }
    }
  }
}
</style>
